#ifndef __UART_H
#define __UART_H

#include <stdint.h>

typedef void (*uart_dispatcher_t)(int uart_no, void *arg);

enum rx_stats{
    rx_idel = 0,
    rx_done
};

struct uart_stats{
    int rx_acc;
    int rx_len;
    int tx_acc;
    enum rx_stats rx_stats;
};

enum uart_fc_type {
  MGOS_UART_FC_NONE = 0,
  MGOS_UART_FC_HW = 1, /* CTS/RTS */
  MGOS_UART_FC_SW = 2, /* XON/XOFF */
};

struct uart_config {
  /* Baud rate, default: 115200 */
  int baud_rate;

  /* Size of the Rx buffer, default: 256 */
  int rx_buf_size;
  /* Enable flow control for Rx (RTS pin), default: off */
  enum uart_fc_type rx_fc_type;
  /*
   * Lingers for this many microseconds after RX fifo is empty in case more
   * data arrives. Default: 15.
   */
  int rx_linger_micros;

  /* Size of the Tx buffer, default: 256 */
  int tx_buf_size;
  /* Enable flow control for Tx (CTS pin), default: off */
  enum uart_fc_type tx_fc_type;

  /* Platform-specific configuration options. */
//   struct uart_dev_config dev;
};

struct uart_state {
  int uart_no;
  struct uart_config cfg;
  uint8_t *rx_buf;
  uint8_t *tx_buf;
  int rx_enabled;
  struct uart_stats stats;
  uart_dispatcher_t dispatcher_cb;
  void *dispatcher_data;
  void *dev_data;
};

void *uart_config_get_default(int);
void uart_config_set_baud_rate(void *, int);
void uart_config_set_rx_params(void *, int, int, int);
void uart_config_set_tx_params(void *, int, int);
int uart_configure(int, void *);
int uart_write(int, char *, int);
int uart_read(int, void *, int);
void uart_set_dispatcher(int uartNo, void(*cb)(int uartNo, void *userdata), void *userdata);

int uart_write_avail(int);
int uart_read_avail(int);
void uart_set_rx_enabled(int, int);
int uart_is_rx_enabled(int);
void uart_flush(int);

#define UART_SYM    \
    DLSYM(uart_set_dispatcher),\
    DLSYM(uart_config_get_default),\
    DLSYM(uart_config_set_baud_rate),\
    DLSYM(uart_config_set_rx_params),\
    DLSYM(uart_config_set_tx_params),\
    DLSYM(uart_configure),\
    DLSYM(uart_write),\
    DLSYM(uart_read),\
    DLSYM(uart_write_avail),\
    DLSYM(uart_read_avail),\
    DLSYM(uart_set_rx_enabled),\
    DLSYM(uart_is_rx_enabled),\
    DLSYM(uart_flush)



#endif